/**
 *  * Copyright (c) 2008 - 2017 Profactor GmbH, TU Wien ACIN, fortiss GmbH
 *  *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *  *
 *  * Contributors:
 *  *   Gerhard Ebenhofer, Alois Zoitl, Ingo Hegny, Monika Wenger, Martin Jobst
 *  *     - initial API and implementation and/or initial documentation
 *  *******************************************************************************
 */
package org.eclipse.fordiac.ide.model.data.provider;

import java.util.ArrayList;
import java.util.Collection;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.edit.provider.ChangeNotifier;
import org.eclipse.emf.edit.provider.ComposeableAdapterFactory;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IChangeNotifier;
import org.eclipse.emf.edit.provider.IDisposable;
import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.emf.edit.provider.IStructuredItemContentProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.fordiac.ide.model.data.util.DataAdapterFactory;

/**
 * This is the factory that is used to provide the interfaces needed to support
 * Viewers. The adapters generated by this factory convert EMF adapter
 * notifications into calls to {@link #fireNotifyChanged fireNotifyChanged}. The
 * adapters also support Eclipse property sheets. Note that most of the adapters
 * are shared among multiple instances. <!-- begin-user-doc --> <!--
 * end-user-doc -->
 * 
 * @generated
 */
public class DataItemProviderAdapterFactory extends DataAdapterFactory
		implements ComposeableAdapterFactory, IChangeNotifier, IDisposable {
	/**
	 * This keeps track of the root adapter factory that delegates to this adapter
	 * factory. <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected ComposedAdapterFactory parentAdapterFactory;

	/**
	 * This is used to implement
	 * {@link org.eclipse.emf.edit.provider.IChangeNotifier}. <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected IChangeNotifier changeNotifier = new ChangeNotifier();

	/**
	 * This keeps track of all the supported types checked by
	 * {@link #isFactoryForType isFactoryForType}. <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * 
	 * @generated
	 */
	protected Collection<Object> supportedTypes = new ArrayList<Object>();

	/**
	 * This constructs an instance. <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	public DataItemProviderAdapterFactory() {
		supportedTypes.add(IEditingDomainItemProvider.class);
		supportedTypes.add(IStructuredItemContentProvider.class);
		supportedTypes.add(ITreeItemContentProvider.class);
		supportedTypes.add(IItemLabelProvider.class);
		supportedTypes.add(IItemPropertySource.class);
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.AnyDerivedType} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected AnyDerivedTypeItemProvider anyDerivedTypeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.AnyDerivedType}. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createAnyDerivedTypeAdapter() {
		if (anyDerivedTypeItemProvider == null) {
			anyDerivedTypeItemProvider = new AnyDerivedTypeItemProvider(this);
		}

		return anyDerivedTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.ArrayType} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected ArrayTypeItemProvider arrayTypeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.ArrayType}. <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createArrayTypeAdapter() {
		if (arrayTypeItemProvider == null) {
			arrayTypeItemProvider = new ArrayTypeItemProvider(this);
		}

		return arrayTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.DirectlyDerivedType} instances.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected DirectlyDerivedTypeItemProvider directlyDerivedTypeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.DirectlyDerivedType}. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createDirectlyDerivedTypeAdapter() {
		if (directlyDerivedTypeItemProvider == null) {
			directlyDerivedTypeItemProvider = new DirectlyDerivedTypeItemProvider(this);
		}

		return directlyDerivedTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.EnumeratedType} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected EnumeratedTypeItemProvider enumeratedTypeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.EnumeratedType}. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createEnumeratedTypeAdapter() {
		if (enumeratedTypeItemProvider == null) {
			enumeratedTypeItemProvider = new EnumeratedTypeItemProvider(this);
		}

		return enumeratedTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.EnumeratedValue} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected EnumeratedValueItemProvider enumeratedValueItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.EnumeratedValue}. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createEnumeratedValueAdapter() {
		if (enumeratedValueItemProvider == null) {
			enumeratedValueItemProvider = new EnumeratedValueItemProvider(this);
		}

		return enumeratedValueItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.StructuredType} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected StructuredTypeItemProvider structuredTypeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.StructuredType}. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createStructuredTypeAdapter() {
		if (structuredTypeItemProvider == null) {
			structuredTypeItemProvider = new StructuredTypeItemProvider(this);
		}

		return structuredTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.Subrange} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected SubrangeItemProvider subrangeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.Subrange}. <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createSubrangeAdapter() {
		if (subrangeItemProvider == null) {
			subrangeItemProvider = new SubrangeItemProvider(this);
		}

		return subrangeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.SubrangeType} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected SubrangeTypeItemProvider subrangeTypeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.SubrangeType}. <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createSubrangeTypeAdapter() {
		if (subrangeTypeItemProvider == null) {
			subrangeTypeItemProvider = new SubrangeTypeItemProvider(this);
		}

		return subrangeTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.ValueType} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected ValueTypeItemProvider valueTypeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.ValueType}. <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createValueTypeAdapter() {
		if (valueTypeItemProvider == null) {
			valueTypeItemProvider = new ValueTypeItemProvider(this);
		}

		return valueTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.ElementaryType} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected ElementaryTypeItemProvider elementaryTypeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.ElementaryType}. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createElementaryTypeAdapter() {
		if (elementaryTypeItemProvider == null) {
			elementaryTypeItemProvider = new ElementaryTypeItemProvider(this);
		}

		return elementaryTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.DerivedType} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected DerivedTypeItemProvider derivedTypeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.DerivedType}. <!-- begin-user-doc
	 * --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createDerivedTypeAdapter() {
		if (derivedTypeItemProvider == null) {
			derivedTypeItemProvider = new DerivedTypeItemProvider(this);
		}

		return derivedTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all
	 * {@link org.eclipse.fordiac.ide.model.data.EventType} instances. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	protected EventTypeItemProvider eventTypeItemProvider;

	/**
	 * This creates an adapter for a
	 * {@link org.eclipse.fordiac.ide.model.data.EventType}. <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter createEventTypeAdapter() {
		if (eventTypeItemProvider == null) {
			eventTypeItemProvider = new EventTypeItemProvider(this);
		}

		return eventTypeItemProvider;
	}

	/**
	 * This returns the root adapter factory that contains this factory. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public ComposeableAdapterFactory getRootAdapterFactory() {
		return parentAdapterFactory == null ? this : parentAdapterFactory.getRootAdapterFactory();
	}

	/**
	 * This sets the composed adapter factory that contains this factory. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public void setParentAdapterFactory(ComposedAdapterFactory parentAdapterFactory) {
		this.parentAdapterFactory = parentAdapterFactory;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public boolean isFactoryForType(Object type) {
		return supportedTypes.contains(type) || super.isFactoryForType(type);
	}

	/**
	 * This implementation substitutes the factory itself as the key for the
	 * adapter. <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Adapter adapt(Notifier notifier, Object type) {
		return super.adapt(notifier, this);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public Object adapt(Object object, Object type) {
		if (isFactoryForType(type)) {
			Object adapter = super.adapt(object, type);
			if (!(type instanceof Class<?>) || (((Class<?>) type).isInstance(adapter))) {
				return adapter;
			}
		}

		return null;
	}

	/**
	 * This adds a listener. <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public void addListener(INotifyChangedListener notifyChangedListener) {
		changeNotifier.addListener(notifyChangedListener);
	}

	/**
	 * This removes a listener. <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public void removeListener(INotifyChangedListener notifyChangedListener) {
		changeNotifier.removeListener(notifyChangedListener);
	}

	/**
	 * This delegates to {@link #changeNotifier} and to
	 * {@link #parentAdapterFactory}. <!-- begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public void fireNotifyChanged(Notification notification) {
		changeNotifier.fireNotifyChanged(notification);

		if (parentAdapterFactory != null) {
			parentAdapterFactory.fireNotifyChanged(notification);
		}
	}

	/**
	 * This disposes all of the item providers created by this factory. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	@Override
	public void dispose() {
		if (anyDerivedTypeItemProvider != null)
			anyDerivedTypeItemProvider.dispose();
		if (arrayTypeItemProvider != null)
			arrayTypeItemProvider.dispose();
		if (directlyDerivedTypeItemProvider != null)
			directlyDerivedTypeItemProvider.dispose();
		if (enumeratedTypeItemProvider != null)
			enumeratedTypeItemProvider.dispose();
		if (enumeratedValueItemProvider != null)
			enumeratedValueItemProvider.dispose();
		if (structuredTypeItemProvider != null)
			structuredTypeItemProvider.dispose();
		if (subrangeItemProvider != null)
			subrangeItemProvider.dispose();
		if (subrangeTypeItemProvider != null)
			subrangeTypeItemProvider.dispose();
		if (valueTypeItemProvider != null)
			valueTypeItemProvider.dispose();
		if (elementaryTypeItemProvider != null)
			elementaryTypeItemProvider.dispose();
		if (derivedTypeItemProvider != null)
			derivedTypeItemProvider.dispose();
		if (eventTypeItemProvider != null)
			eventTypeItemProvider.dispose();
	}

}
